﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using Vlc.DotNet.Forms;
using System.Threading;

namespace vlcWinForm
{
    public partial class VlcPlayerControl : UserControl
    {
        private bool vlcControlTimeChanged = false;
        private Form fullScreenForm = null;
        private Form splitScreenForm = null;
        private VlcPlayerControl fullScreenvlcPlayerControl = null;
        //private List<VlcPlayerControl> splitScreenvlcPlayerControlList = null;
        private FourVlcPlayerControl fourVlcPlayerControl = null;
        private string videoFileName;
        private int trackBarMaximum = -1;
        private int trackBarMinimum = -1;
        private int time;
        public VlcPlayerControl()
        {
            InitializeComponent();
            //Init();
        }

        public void Play(string fileName)
        {
            this.videoFileName = fileName;
            FileInfo file = new FileInfo(fileName);
            
            //vlcControl.Play(file);
            vlcControl.SetMedia(file);
            vlcControl.Play();
            if (trackBarMinimum >= 0)
                vlcControl.Time = trackBarMinimum;
        }

        public void SetTrackBarMinMax(int min, int max)
        {
            trackBarMinimum = min;
            trackBarMaximum = max;
            this.trackBar1.Minimum = min;
            this.trackBar1.Maximum = max;
        }

        private void Init()
        {
            vlcControl = new VlcControl();
            var currentAssembly = Assembly.GetEntryAssembly();
            var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;
            // Default installation path of VideoLAN.LibVLC.Windows
            var libDirectory = new DirectoryInfo(Path.Combine(currentDirectory, "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64"));

            vlcControl.BeginInit();
            vlcControl.VlcLibDirectory = libDirectory;
            vlcControl.Dock = DockStyle.Fill;
            vlcControl.LengthChanged += vlcControl_LengthChanged;
            vlcControl.TimeChanged += vlcControl_TimeChanged;
            vlcControl.EncounteredError += vlcControl_EncounteredError;
            vlcControl.EndInit();
            this.Controls.Add(vlcControl);

            /*vlcControl = new VlcControl();
            vlcControl.VlcLibDirectoryNeeded += vlcControl_VlcLibDirectoryNeeded;
            vlcControl.LengthChanged += vlcControl_LengthChanged;
            vlcControl.TimeChanged += vlcControl_TimeChanged;
            vlcControl.EncounteredError += vlcControl_EncounteredError;
            vlcControl.Dock = DockStyle.Fill;
            this.Controls.Add(vlcControl);*/
            /*var options = new string[]
            {
                // VLC options can be given here. Please refer to the VLC command line documentation.
            };
            videoControl.SourceProvider.CreatePlayer(vlcLibDirectory, options);*/

            // This can also be called before EndInit
            //videoControl.SourceProvider.MediaPlayer.Log += (_, args) =>
            //{
            //    string message = $"libVlc : {args.Level} {args.Message} @ {args.Module}";
            //    Logger.Info(message);
            //};

            //videoControl.SourceProvider.MediaPlayer.Play(ExeBin.Instance.GetRtmpUrl());
        }

        private void vlcControl_VlcLibDirectoryNeeded(object sender, Vlc.DotNet.Forms.VlcLibDirectoryNeededEventArgs e)
        {
            var currentAssembly = Assembly.GetEntryAssembly();
            var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;
            // Default installation path of VideoLAN.LibVLC.Windows
            e.VlcLibDirectory = new DirectoryInfo(Path.Combine(currentDirectory, "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64"));
        }

        private void vlcControl_LengthChanged(object sender, Vlc.DotNet.Core.VlcMediaPlayerLengthChangedEventArgs e)
        {
            if (trackBarMaximum != -1)
                return;
            if (this.IsHandleCreated)
            {
                this.Invoke(new Action(delegate ()
                {
                    trackBar1.Maximum = (int)e.NewLength;
                }));
            }
            else
            {
                this.HandleCreated += delegate (object sender2, EventArgs e2)
                {
                    this.Invoke(new Action(delegate ()
                    {
                        trackBar1.Maximum = (int)e.NewLength;
                    }));
                };
            }
        }

        private void vlcControl_TimeChanged(object sender, Vlc.DotNet.Core.VlcMediaPlayerTimeChangedEventArgs e)
        {
            vlcControlTimeChanged = true;
            try
            {
                this.Invoke(new Action(delegate ()
                {
                    if ((int)e.NewTime < trackBar1.Minimum)
                        trackBar1.Value = trackBarMinimum;
                    else if ((int)e.NewTime > trackBar1.Maximum)
                        trackBar1.Value = trackBarMaximum;
                    else
                        trackBar1.Value = (int)e.NewTime;
                }));
            }
            finally
            {
                vlcControlTimeChanged = false;
            }
        }

        private void trackBar1_ValueChanged(object sender, EventArgs e)
        {
            if (!vlcControlTimeChanged)
            {
                vlcControl.Time = trackBar1.Value;
                //MessageBox.Show("trackBar1_ValueChanged");
            }
        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            //string fileName = @"D:\Projects\C#\vlcWinForm\bin\Debug\b_x264.mp4";
            //FileInfo file = new FileInfo(fileName);
            if (vlcControl.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Paused)
                vlcControl.Play();
            else
            {
                vlcControl.Play();
                if (trackBarMinimum >= 0)
                    vlcControl.Time = trackBarMinimum;
            }
        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            vlcControl.Pause();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            vlcControl.Stop();
        }

        private void btnAccelerate_Click(object sender, EventArgs e)
        {
            vlcControl.Rate += 1;
        }

        private void btnSlowDown_Click(object sender, EventArgs e)
        {
            if (vlcControl.Rate > 1)
                vlcControl.Rate -= 1;
        }

        private void btnFastForward_Click(object sender, EventArgs e)
        {
            if (vlcControl.Time + 10000 < vlcControl.Length)
                vlcControl.Time += 10000;
            else
                vlcControl.Time = vlcControl.Length;
        }

        private void btnFastBackward_Click(object sender, EventArgs e)
        {
            if (vlcControl.Time - 10000 > 0)
                vlcControl.Time -= 10000;
            else
                vlcControl.Time = 0;
        }

        private void vlcControl_EncounteredError(object sender, Vlc.DotNet.Core.VlcMediaPlayerEncounteredErrorEventArgs e)
        {
            MessageBox.Show(e.ToString());
        }

        public bool Playing()
        {
            return vlcControl.IsPlaying || fullScreenvlcPlayerControl != null && fullScreenvlcPlayerControl.Playing();
        }

        private void btnFullScreen_Click(object sender, EventArgs e)
        {
            if (fullScreenForm == null)
            {
                fullScreenForm = new Form();
                fullScreenForm.Text = "全屏";
                if (fullScreenvlcPlayerControl == null)
                {
                    fullScreenvlcPlayerControl = new VlcPlayerControl();
                    fullScreenvlcPlayerControl.Dock = DockStyle.Fill;
                    fullScreenForm.Controls.Add(fullScreenvlcPlayerControl);
                }
                fullScreenForm.FormClosing += delegate (object sender2, FormClosingEventArgs e2)
                {
                    fullScreenvlcPlayerControl.Close();
                    /*if (fullScreenvlcPlayerControl.Playing())
                    {
                        e2.Cancel = true;
                        MessageBox.Show("必须先暂停视频，才能退出");
                    }*/
                };
            }
            fullScreenForm.WindowState = FormWindowState.Maximized;
            fullScreenForm.Show();
            fullScreenvlcPlayerControl.Play(this.videoFileName);
        }

        private void btnSplitScreen_Click(object sender, EventArgs e)
        {
            //if (splitScreenForm == null)
            {
                splitScreenForm = new Form();
                splitScreenForm.Text = "分屏";
                //if (fourVlcPlayerControl == null)
                {
                    fourVlcPlayerControl = new FourVlcPlayerControl();
                    fourVlcPlayerControl.Dock = DockStyle.Fill;
                    splitScreenForm.Controls.Add(fourVlcPlayerControl);
                }
                splitScreenForm.FormClosing += delegate (object sender2, FormClosingEventArgs e2)
                {
                    fourVlcPlayerControl.Close();
                    /*if (fourVlcPlayerControl.Playing())
                    {
                        e2.Cancel = true;
                        MessageBox.Show("必须先暂停视频，才能退出");
                    }*/
                };
            }
            splitScreenForm.WindowState = FormWindowState.Maximized;
            splitScreenForm.Show();
            fourVlcPlayerControl.Play(this.videoFileName, (int)this.vlcControl.Length);
        }

        public void Close()
        {
            vlcControl.Pause();
            Application.DoEvents();
            fullScreenvlcPlayerControl?.Close();
            Application.DoEvents();
            fourVlcPlayerControl?.Close();
            Application.DoEvents();
        }
    }
}
